#ifndef _CLIENT_H_
#define _CLIENT_H_

#include "types.h"
#include "mutex.h"
#include "thread.h"

namespace reldt {

class Client
{
public:
	Client();
	~Client();

	int connect(const char *src_ip, u16 src_port, const char *dst_ip, u16 dst_port); //block

    int disconn();
	virtual void on_disconn() {}

    int send(const char *msg, int msglen);
    virtual void on_finish() {}

	virtual void on_recv(const char *msg, int msglen) {}

private:
    enum
    {
        STATE_IDLE,
        STATE_CONNECTING,
        STATE_CONNECTED,
        STATE_DISCONNING,
    };

    int state;
    int sock;

    struct sockaddr_in self;
    struct sockaddr_in peer;

    u32 sessid;     //connect session id
    u32 send_tid;   //send transaction id
    u32 recv_tid;   //recv transaction id
	std::list<string> send_list;
	std::list<string> recv_list;

    Thread thread;
    Mutex mutex;

    void clear();
    int send_str(const char *msg, int len);
	int recv_str(char *buf, int len, bool newconn);
	int send_conn(u32 sessid);
    int send_disc(u32 sessid);
    int send_disc_cfm(u32 sessid);
    int send_pack(u32 sessid, u32 tid, u32 seq, const string &pack);
	int send_pack_cfm(u32 sessid, u32 tid, u32 seq);
	static void entry(void * arg);
	int process();
};

}
#endif //_CLIENT_H_